<!doctype html>
<html>

<head>
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
    <meta charset="utf-8" />
    <title>粒子连线</title>
    <style>
        html,
        body {
            background: #000;
            overflow: hidden;
        }
    </style>
</head>

<body>
    <canvas id="cvs"></canvas>
    <script>
        (function() {
            var PI = Math.PI;
            var cvs = document.getElementById('cvs');
            var stop = false;
            try {
                var requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame
                var ctx = cvs.getContext('2d');
            } catch (e) {
                stop = true;
            }
            console.log(requestAnimationFrame)
            if (stop || !requestAnimationFrame || !ctx) {
                return
            }

            //碰撞半径
            var minLineDist = 200;


            var w = cvs.width = window.screen.width;
            var h = cvs.height = window.screen.height;
            //重绘标志
            var flag = Math.sqrt(w * w + h * h) / 2
            var ox = w / 2;
            var oy = h / 2;

            var box = [];
            for (var i = 0; i < 100; i++) {
                box.push({
                    r: 0,
                    R: Math.random() * h,
                    d: deg(Math.random() * 360),
                    v: Math.random() * 1,
                    a: 1
                })
            }

            var len = box.length;
            ctx.fillStyle = '#fff';
            ctx.shadowColor = '#ff0';
            ctx.shadowBlur = 20;
            ctx.strokeStyle = '#fff';
            requestAnimationFrame(loop)


            function loop() {

                ctx.clearRect(0, 0, w, h);
                ctx.beginPath();
                for (var i = 0; i < len; i++) {
                    if (box[i].R > flag) {
                        box[i].R = Math.random() * flag;
                        box[i].r = 5;
                        box[i].d = deg(Math.random() * 360);
                        box[i].v = Math.random();
                    }
                    box[i].R += box[i].v;
                    box[i].v += Math.random() * 0.01;
                    box[i].r = 5 * box[i].R / flag + 5;
                    box[i].d += box[i].v / box[i].R
                    fillStar(box[i]);
                }
                ctx.fill();
                ctx.beginPath();
                for (var i = 0; i < len; i++) {
                    for (var j = i + 1; j < len; j++) {
                        checkHit(box[i], box[j]);
                    }
                }
                ctx.stroke();
                requestAnimationFrame(loop)

            }


            function deg(num) {
                return (PI * num) / 180
            }

            function fillStar(item) {
                var x = getPos(item.R, item.d).x;
                var y = getPos(item.R, item.d).y;
                ctx.arc(x, y, item.r, 0, deg(360));
                ctx.closePath();
            }

            function checkHit(a, b) {
                var ap = getPos(a.R, a.d);
                var bp = getPos(b.R, b.d);
                var dx = ap.x - bp.x;
                var dy = ap.y - bp.y;
                var dist = Math.sqrt(dx * dx + dy * dy);
                if (dist < minLineDist && (a.r > 6 || b.r > 6)) {
                    ctx.moveTo(ap.x, ap.y);
                    ctx.lineTo(bp.x, bp.y);
                    ctx.closePath();
                }

            }


            /*建立圆坐标转换*/
            function getPos(R, d) {
                return {
                    x: R * Math.cos(d) + ox,
                    y: R * Math.sin(d) + oy,
                }
            }
        })();
    </script>
</body>

</html>